package server;

import SBLib.File;
import SBLib.IPAddresses;
import SBLib.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *  Handles the replication. When the server receives a request that requires replication, it spawns ReplicatorPusher threads to pass the request to all other 
 *  replication servers.
 * 
 * @author BrandonNeal
 */
public class Replicator {
    
    
    private int ReplicatorPort = 9998;
    private int TIMEOUT = 3000;
    final private ArrayList<File> Files;
    final private ArrayList<User> Users;
    
    
    public Replicator(ArrayList<File> files, ArrayList<User> users)
    {
        this.Files = files;
        this.Users = users;
    }
    /**
     * Push message to all other RMs. Until we require data consistency, don't care if there was an issue with the data push.
     * @param Message 
     */
    public void Replicate(String Message)
    {
        ArrayList<Thread> threads = new ArrayList<Thread>();
        
        for(String ip:IPAddresses.RMs)
        {
            System.out.println("Connecting to "+ip);
            ReplicatorPusher rp = new ReplicatorPusher(ip,Message, this.TIMEOUT, this.ReplicatorPort);
            //threads.add(rp);
        }
        
        //Join all threads.
        /*
        for(int i=0; i<threads.size(); i++)
        {
            try 
            {
                threads.get(i).join();
            } 
            catch (InterruptedException ex) 
            {
                Logger.getLogger(Replicator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }*/
    }
    public void new_user(String username, String password)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"NEW_USER",username,password}));
    }
    public void new_file(String filename, String content)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"NEW_FILE",filename,content}));
    }
    public void edit_file(String filename, String newContent)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"EDIT_FILE",filename,newContent}));
    }
    public void rename_file(String filename, String newFilename)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"RENAME_FILE",filename,newFilename}));
    }
    public void delete_file(String filename)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"DELETE_FILE",filename}));
    }
    public void lock_file(String filename, String username)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"LOCK_FILE",filename,username}));
    }
    public void unlock_file(String filename, String username)
    {
        Response r = new Response();
        this.Replicate(r.buildString(new String[]{"UNLOCK_FILE",filename,username}));
    }
    
    
    

    
   
    
}

